package top.frsf.rpc.server;

import io.netty.bootstrap.Bootstrap;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioSocketChannel;
import lombok.extern.slf4j.Slf4j;
import top.frsf.rpc.channel.ClientChannelInitializer;

/**
 * @author He Kuntao
 * @since 2025/7/2 13:40
 */
@Slf4j
public class NettyRpcClient {
    /**
     * 共享的Worker线程组
     */
    private final EventLoopGroup workerGroup = new NioEventLoopGroup();
    /**
     * 引导类
     */
    private final Bootstrap bootstrap;

    public NettyRpcClient() {
        this.bootstrap = new Bootstrap()
                .group(workerGroup)
                .channel(NioSocketChannel.class)
                .handler(new ClientChannelInitializer())
                .option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 3000)
                .option(ChannelOption.SO_KEEPALIVE, true);
    }

    /**
     * 创建客户端连接
     *
     * @param ip   服务IP
     * @param port 服务端口
     * @return 客户端连接
     * @throws InterruptedException 连接中断异常
     */
    public Channel createConnection(String ip, int port) throws InterruptedException {
        ChannelFuture future = bootstrap.connect(ip, port).sync();
        if (!future.isSuccess()) {
            throw new IllegalStateException("Connection failed to " + ip + ":" + port, future.cause());
        }

        Channel channel = future.channel();
        log.info("Successfully connected to {}:{} (Channel: {})", ip, port, channel.id());
        return channel;
    }

    /**
     * 关闭客户端工作现场组
     */
    public void shutdown() {
        workerGroup.shutdownGracefully();
    }
}
